package com.zzw.ratelimter;

import com.zzw.interceptor.RedisRateLimterInterceptor;
import com.zzw.properties.RedisRateLimterProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.scripting.support.ResourceScriptSource;

import java.util.List;

/**
 * @author Administrator
 */
@Configuration
public class RedisRateLimiterConfiguration {

    @Bean
    public RedisRateLimterProperties redisRateLimterProperties() {
        return new RedisRateLimterProperties();
    }

    @Bean
    public RedisScript<?> redisRequestRateLimiterScript() {
        DefaultRedisScript redisScript = new DefaultRedisScript();
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("META-INF/script/request_rate_limiter.lua")));
        redisScript.setResultType(List.class);
        return redisScript;
    }

    @Bean
    public RedisRateLimiter redisRateLimiter(StringRedisTemplate stringRedisTemplate, @Qualifier("redisRequestRateLimiterScript") RedisScript<List<Long>> redisScript
            , @Qualifier("redisRateLimterProperties") RedisRateLimterProperties redisRateLimterProperties) {
        return new RedisRateLimiter(stringRedisTemplate, redisScript, redisRateLimterProperties);
    }

    @Bean
    @ConditionalOnProperty(prefix = "zzw.commons.server.redis.limter", name = "enable")
    public RedisRateLimterInterceptor redisRateLimterInterceptor(@Qualifier("redisRateLimterProperties") RedisRateLimterProperties redisRateLimterProperties
            , @Qualifier("redisRateLimiter") RedisRateLimiter redisRateLimter) {
        return new RedisRateLimterInterceptor(redisRateLimterProperties, redisRateLimter);
    }
}
